package com.example.schoolblog.blog.Service;

import com.example.schoolblog.blog.Dto.NotificationDTO;
import com.example.schoolblog.blog.Dto.PaginationDTO;
import com.example.schoolblog.blog.Enums.NotificationStatusEnum;
import com.example.schoolblog.blog.Enums.NotificationTypeEnum;
import com.example.schoolblog.blog.Exception.CustomizeErrorCode;
import com.example.schoolblog.blog.Exception.CustomizeException;
import com.example.schoolblog.blog.Mapper.NotificationMapper;
import com.example.schoolblog.blog.Model.*;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class NotificationService {

    @Autowired
    private NotificationMapper notificationMapper;

    /**
     *
     * @param id  用户的id
     * @param page 页数
     * @param size  每页个数
     * @return
     */
    public PaginationDTO list(Long id, Integer page, Integer size) {
        PaginationDTO paginationDTO = new PaginationDTO();
        //计算通知的总数
        NotificationExample notificationExample = new NotificationExample();
        notificationExample.createCriteria().andReceiverEqualTo(id);
        int totalCount = (int)notificationMapper.countByExample(notificationExample);
        //对分页类参数进行设置
        paginationDTO.setPagination(totalCount,page,size);
        //计算数据库查询的偏移量值
        Integer offset = size * (paginationDTO.getPage() - 1);
        //取得当前用户的全部通知
        NotificationExample example = new NotificationExample();
        example.createCriteria()
                .andReceiverEqualTo(id);
        example.setOrderByClause("gmt_create desc");
        List<Notification> notifications = notificationMapper.selectByExampleWithRowbounds(example,new RowBounds(offset,size));
        if(notifications.size() == 0) {
            return paginationDTO;
        }
        List<NotificationDTO> notificationDTOS = new ArrayList<>();

        for(Notification notification : notifications){
            NotificationDTO notificationDTO = new NotificationDTO();
            BeanUtils.copyProperties(notification,notificationDTO);
            notificationDTO.setTypeName(NotificationTypeEnum.nameOfType(notification.getType()));
            notificationDTOS.add(notificationDTO);
        }
        paginationDTO.setData(notificationDTOS);
        return paginationDTO;
    }

    /**
     *
     * @param id 接收者的id
     * @return 返回用户的通知数
     */
    public Long unreadCount(Long id) {
        NotificationExample notificationExample = new NotificationExample();
        notificationExample.createCriteria()
                .andReceiverEqualTo(id)
                .andStatusEqualTo(NotificationStatusEnum.UNREAD.getStatus());
        return notificationMapper.countByExample(notificationExample);
    }

    /**
     *
     * @param id 通知的id
     * @param user 当前用户
     * @return 返回通知Dto
     */
    public NotificationDTO read(Long id, User user) {
        //通过id查询通知
        Notification notification = notificationMapper.selectByPrimaryKey(id);
        //在网址上通知的id输入错误时
        if(notification == null){
            throw new CustomizeException(CustomizeErrorCode.NOTIFICATION_NOT_FOUND);
        }
        //防止非本用户读取自己的通知
        if(!Objects.equals(notification.getReceiver(),user.getId())){
            throw new CustomizeException(CustomizeErrorCode.READ_NOTIFICATION_FAIL);
        }
        //点击通知了就设置已读
        notification.setStatus(NotificationStatusEnum.READ.getStatus());
        notificationMapper.updateByPrimaryKey(notification);
        //封装进dto
        NotificationDTO notificationDTO = new NotificationDTO();
        BeanUtils.copyProperties(notification,notificationDTO);
        //设置类型名称：回复问题还是评论
        notificationDTO.setTypeName(NotificationTypeEnum.nameOfType(notification.getType()));
        return notificationDTO;
    }
}
